﻿using System;
using System.Collections.Generic;
using NHibernate.Mapping.ByCode;
using Xenta.Enums;

namespace Xenta.Entities
{
    /// <summary>
    /// Represents the forum access restriction.
    /// </summary>
    /// <remarks><pre>
    /// The entity regarding the disclosure level.
    /// 
    /// + Entire
    ///  + Extended
    ///   + Base
    ///    | - Forum(of the Primary level)
    ///    | - Role(of the Keys level)
    ///    | - AccessRights
    ///    + Keys
    ///     + Primary
    ///      | - EntityID
    /// 
    /// Note: upper level includes lower level.
    /// </pre></remarks>
    public class ForumAccessRuleEntity : Entity
    {
        #region Fields

        private ForumAccessRights _accessRights;

        #endregion

        #region Ctors

        /// <summary>
        /// Initializes a new class instance.
        /// </summary>
        public ForumAccessRuleEntity()
        {
            _accessRights = ForumAccessRights.ReadOnly;
        }

        #endregion

        #region Properties

        /// <summary>
        /// Gets or sets the forum.
        /// </summary>
        public virtual ForumEntity Forum
        {
            get;
            set;
        }

        /// <summary>
        /// Gets or sets the role.
        /// </summary>
        public virtual RoleEntity Role
        {
            get;
            set;
        }

        /// <summary>
        /// Gets or sets the forum access rights.
        /// </summary>
        public virtual ForumAccessRights AccessRights
        {
            get
            {
                return _accessRights;
            }
            set
            {
                _accessRights = value;
            }
        }

        #endregion

        #region Utilities

        protected override void Disclose(IDictionary<String, Object> obj,
            DisclosureLevel level,
            IDictionary<String, String> options)
        {
            base.Disclose(obj, level, options);
            if(level >= DisclosureLevel.Base)
            {
                obj["Forum"] = Forum.Disclose(DisclosureLevel.Primary, options);
                obj["Role"] = Role.Disclose(DisclosureLevel.Keys, options);
                obj["AccessRights"] = AccessRights.ToString();
            }
        }

        #endregion
    }

    /// <summary>
    /// The entity NHibernate mapping.
    /// </summary>
    public class ForumAccessRuleMapping : EntityMapping<ForumAccessRuleEntity>
    {
        /// <summary>
        /// Initializes a new class instance.
        /// </summary>
        public ForumAccessRuleMapping()
        {
            Table("fwk_ForumAccessRules");
            Id(x => x.EntityID, m =>
            {
                m.Column("RuleID");
                m.Generator(Generators.Identity);
            });
            ManyToOne(x => x.Forum, m =>
            {
                m.Column("ForumID");
                m.ForeignKey("FK_fwk_MForumRoles_fwk_Forums");
                m.Index("IX_fwk_MForumRoles");
                m.NotNullable(true);
                m.Fetch(FetchKind.Join);
            });
            ManyToOne(x => x.Role, m =>
            {
                m.Column("RoleID");
                m.ForeignKey("FK_fwk_MForumRoles_fwk_Roles");
                m.Index("IX_fwk_MForumRoles");
                m.NotNullable(true);
                m.Fetch(FetchKind.Join);
            });
            Property(x => x.AccessRights, m =>
            {
                m.Column("AccessRights");
                m.NotNullable(true);
            });
        }
    }
}
